package org.springframework.aop.org.springframework.aop.framework;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import org.springframework.aop.org.springframework.aop.AdvisedSupport;

import java.lang.reflect.Method;

/**
 * @author admin
 */
public class CglibSubclassingAopProxy implements AopProxy {

    private AdvisedSupport advised;

    public CglibSubclassingAopProxy(AdvisedSupport advisedSupport) {
        this.advised = advisedSupport;
    }

    @Override
    public Object getProxy() {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(advised.getTargetSource().getTarget().getClass());
        enhancer.setInterfaces(advised.getTargetSource().getTargetClass());
        enhancer.setCallback((MethodInterceptor) (obj, method, args, methodProxy) -> {
            if (advised.getMethodMatcher().matches(method, advised.getTargetSource().getTarget().getClass())) {
                return advised.getInterceptor().invoke(new ReflectMethodInvocation(method, args, advised.getTargetSource().getTarget()));
            } else {
                return methodProxy.invoke(advised.getTargetSource().getTarget(), args);
            }
        });
        return enhancer.create();
    }
}
